package com.engine.workflow.cmd.requestForm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cloudstore.dev.api.util.TextUtil;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.biz.EncryptConfigBiz;
import com.engine.workflow.biz.requestForm.FileBiz;
import com.engine.common.util.ParamUtil;
import com.engine.workflow.biz.requestForm.LinkageLogBiz;
import weaver.conn.RecordSet;
import weaver.docs.docs.DocManager;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.workflow.datainput.DynamicDataInput;
import java.util.*;
import weaver.log4j.Module;
import javax.servlet.http.HttpServletRequest;

import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.workflow.biz.requestForm.RequestFormBiz;
import com.engine.workflow.entity.requestForm.FieldInfo;
import com.engine.workflow.entity.requestForm.FieldValueBean;
import com.api.workflow.util.ServiceUtil;
import weaver.workflow.workflow.WorkflowConfigComInfo;

/**
 * @author sf
 */
public class LinkageDataInputCmd extends AbstractCommonCommand<Map<String,Object>>{
	
	private HttpServletRequest request;
	//解决同样的触发字段，多个触发设置，若触发设置1能查出结果，触发设置2查不出结果，此情况下以能查出结果的作为有效结果
	Map<String,FieldValueBean> emptyResultClearObj = new HashMap<>();	//存储清空的对象
	Map<String,FieldValueBean> vaildResultChangeObj = new HashMap<>();	//存储有效的结果对象
	private Map<String,Object> linkageSqlMap = new HashMap<>();

	public LinkageDataInputCmd(HttpServletRequest request, User user){
		this.request = request;
		this.user = user;
	}

    /**
     * 字段联动，主表联动主表、主表联动明细表
     */
    public Map<String,Object> execute(CommandContext commandContext){
		//记录联动日志
		Map<String, Object> reqParams = ParamUtil.request2Map(request);
		String uuid=  UUID.randomUUID().toString().replace("-", "").toUpperCase();
		LinkageLogBiz linkageLogBiz = new LinkageLogBiz(user,0,reqParams,uuid);
		boolean needWrite = linkageLogBiz.needWriteLog();
		if (needWrite){
			linkageLogBiz.writeLinkageLog();
		}
        Map<String, Object> result = new HashMap<String, Object>();
        RecordSet rs = new RecordSet();
        RecordSet rsObj = new RecordSet();
        String workflowid = request.getParameter("workflowid");
        String datainputids = request.getParameter("linkageid");
        String nodeid = request.getParameter("nodeid");
		int requestid = Util.getIntValue(Util.null2String(request.getParameter("requestid")));
		boolean showAI = "1".equals(Util.null2String(request.getParameter("showAI")));
        String formid = "";
        String isbill = "";
        int rowIndex = 0;
		rs.executeSql("select formid,isbill from workflow_base where id="+workflowid);
		if(rs.next()){
			formid = rs.getString("formid");
			isbill = rs.getString("isbill");
		}
		//表单所有字段信息
		Map<String,FieldInfo> fieldmap = RequestFormBiz.getFieldInfoByFormid(formid, isbill);
        String arrayentry[] = Util.splitString(datainputids, ",");
        for(int temp=0; temp<arrayentry.length; temp++){
        	String datainputid= arrayentry[temp];
        	String trgFieldName = Util.null2String((String)request.getParameter("triFieldid_"+datainputid));
        	//int rowIndex = Util.getIntValue(Util.null2String(request.getParameter("rowIndexStr_"+datainputid)));
        	String rowIndexStr = Util.null2String(request.getParameter("rowIndexStr_"+datainputid));
        	String arrayindexid[] = Util.splitString(rowIndexStr, ",");
        	if(trgFieldName != null && !trgFieldName.trim().equals("") ){
		        Map<String,FieldValueBean> changeValue = new HashMap<String,FieldValueBean>();
		        Map<String,Object> addDetailInfo = new HashMap<String,Object>();
		        String linkageSql = "";
		        boolean resultOutOfLimit = false;
				//用于存储执行的sql语句，和sql语句执行结果
				Map<String,String> sqlResultMap = new HashMap<String,String>();
        		for(int s=0; s<arrayindexid.length; s++){
	        		rowIndex = Util.getIntValue(arrayindexid[s]);
	        		DynamicDataInput DDI = new DynamicDataInput(workflowid,trgFieldName,isbill);
					DDI.setRequestid(requestid);
	        		//查询将当前字段作为取值参数的所有联动信息
	        		String entryid = "";
	        		Hashtable outdatahash = new Hashtable();
	    			rsObj.executeSql("select entryid,IsCycle,WhereClause from Workflow_DataInput_main where id="+datainputid+" order by orderid");
	    			ArrayList outdatasList=new ArrayList();
	    			ArrayList outfieldnamelist=new ArrayList();
	    			ArrayList groupids = null ;
	    			if(rsObj.next()){
	    				entryid = rsObj.getString("entryid");
	    				String type = getEntryType(entryid);
	    				groupids = DDI.GetOutFieldIndex(datainputid);//查询出明细个数
	    				//获取联动信息中的 所有取值字段名称 及 取值字段值。
	    				ArrayList infieldnamelist = DDI.GetInFieldName(datainputid);
	    				for(int i=0;i<infieldnamelist.size();i++){
	    					//String paramName = datainputid+"|"+(String)infieldnamelist.get(i)+suffixField;
	    					String paramName = (String)infieldnamelist.get(i);
	    					if(rowIndex >= 0)
	    			   			paramName += "_"+rowIndex;
	    					String inputFieldValue = Util.null2String(request.getParameter(paramName));
							inputFieldValue = EncryptConfigBiz.getDecryptData(inputFieldValue);
	    					//inputFieldValue = inputFieldValue.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
	    					inputFieldValue = inputFieldValue.replace("\n", "<br>");
	    					//记录日志信息
	    					DDI.SetInFields((String)infieldnamelist.get(i),inputFieldValue);
	    				}
	    				//获取联动信息中的 所有条件字段名称 及 条件字段值。
	    				ArrayList conditionfieldnameList = DDI.GetConditionFieldName(datainputid);
	    				for(int j=0;j<conditionfieldnameList.size();j++){
	    					DDI.SetConditonFields((String)conditionfieldnameList.get(j),Util.null2String(request.getParameter(datainputid+"|"+(String)conditionfieldnameList.get(j))));
	    				}
	    		        //DDI.GetOutDataWithIndex(datainputid,type);
	    		        //outfieldnamelist = DDI.GetOutFieldNameList();
	    		        //outdatasList = DDI.GetOutDataWithIndex(datainputid,type);
						DDI.GetOutData(datainputid);
				        outfieldnamelist = DDI.GetOutFieldNameList();
				        outdatasList = DDI.GetOutDataList();
						//linkageSql = DDI.getLinkageSql();
						resultOutOfLimit = DDI.getResultOutOfLimit();
	    		        //DDI.GetOutData(datainputid);
	    		        //outdatasList = DDI.GetOutDataList();
	    		      	//赋值字段为主表字段的更新
	    				if(type.equals("0")){
	    					//当赋值字段为主表字段时， outdatasList仅包含一个元素。
	    					
	    					/************** 主表联动主表start **************/
	    					for(int j=0; j<outfieldnamelist.size(); j++){
    				 			String fieldName = (String)outfieldnamelist.get(j);
    				 			FieldInfo info = fieldmap.get(fieldName.substring(5));
    				 			if(info == null || info.getIsdetail() == 1)
    				 				continue;
								FieldValueBean clearobj = this.buildClearObj(trgFieldName+"|"+fieldName, outdatasList.size() > 0);
    				 		    changeValue.put(fieldName, clearobj);
    				 		}
	    					for(int i=0;i<outdatasList.size();i++){
	    				 		outdatahash = (Hashtable)outdatasList.get(i);
	    				 		for(int j=0; j<outfieldnamelist.size(); j++){
	    				 			String fieldName = (String)outfieldnamelist.get(j);
	    				 		    String fieldValue = (String)outdatahash.get(fieldName);
									FieldInfo info = fieldmap.get(fieldName.substring(5));
									if(info == null || info.getIsdetail() == 1)
	    				 		   		continue;
									
									if(!(info.getHtmltype()==2&&info.getDetailtype()==2)){ //多行文本框不去HTML元素
										fieldValue = Util.toExcelData(fieldValue);
									}
	    				 		   	
									FieldValueBean changeobj = this.buildValueObj(fieldValue, info, fieldName);
									this.vaildResultChangeObj.put(trgFieldName+"|"+fieldName, changeobj);
	    				 		    changeValue.put(fieldName, changeobj);
	    				 		}
	    	       			}
	    					/************** 主表联动主表end **************/
	    					
	    					/************** 主表联动明细表start **************/
	    					String trgFieldNamevalue = Util.null2String((String)request.getParameter("field"+trgFieldName));
							for(int dtidx = 0 ; dtidx < groupids.size() ; dtidx++){
								int tmpgroupid = Util.getIntValue(groupids.get(dtidx).toString(),1) ;
								List<Map<String,FieldValueBean>> addlist = new ArrayList<Map<String,FieldValueBean>>();
								if(!"".equals(trgFieldNamevalue)) {
									outfieldnamelist = DDI.GetOutFieldNameListWithIndex(datainputid,tmpgroupid+"") ;
									outdatasList = DDI.GetOutDataWithIndex(datainputid,tmpgroupid+"");
									for(int i=0;i<outdatasList.size();i++){
										Map<String,FieldValueBean> detailmap = new HashMap<String,FieldValueBean>();
										outdatahash = (Hashtable)outdatasList.get(i);
										for(int j=0; j<outfieldnamelist.size(); j++){
											String tempfieldname = outfieldnamelist.get(j).toString();
											String tempValue = (String)outdatahash.get(tempfieldname);
											FieldInfo info = fieldmap.get(tempfieldname.substring(5));
											if(info == null || info.getIsdetail() == 0)
												continue;
											detailmap.put(tempfieldname, this.buildValueObj(tempValue, info, tempfieldname));
										}
										addlist.add(detailmap);
									}
								}
								if(tmpgroupid > 0)
									addDetailInfo.put("detail_"+tmpgroupid, addlist);
							}
	    					/************** 主表联动明细表end **************/
	    		       	}else if(type.equals("1")){
	    		       		/************** 明细联动明细start **************/
	    		       		for(int j=0; j<outfieldnamelist.size(); j++){
					 			String fieldName = (String)outfieldnamelist.get(j);
					 			FieldInfo info = fieldmap.get(fieldName.substring(5));
								FieldValueBean clearobj = this.buildClearObj(trgFieldName+"|"+fieldName+"_"+rowIndex, outdatasList.size() > 0);
					 		    changeValue.put(fieldName+"_"+rowIndex, clearobj);
					 		}
	    					for(int i=0;i<outdatasList.size();i++){
	    				 		outdatahash = (Hashtable)outdatasList.get(i);
	    				 		for(int j=0; j<outfieldnamelist.size(); j++){
	    				 			String fieldName = (String)outfieldnamelist.get(j);
	    				 		    String fieldValue = (String)outdatahash.get(fieldName);
									FieldInfo info = fieldmap.get(fieldName.substring(5));
									if(info == null)
	    				 		   		continue;
									
									if(!(info.getHtmltype()==2&&info.getDetailtype()==2)){   //多行文本框不去HTML元素
										fieldValue = Util.toExcelData(fieldValue);
									}
	    				 		    
									FieldValueBean changeobj = this.buildValueObj(fieldValue, info, fieldName+"_"+rowIndex);
									this.vaildResultChangeObj.put(trgFieldName+"|"+fieldName+"_"+rowIndex, changeobj);
						 		    changeValue.put(fieldName+"_"+rowIndex, changeobj);
	    				 		}
	    	       			}
	    					/************** 明细联动明细end **************/
	    		       	}
	    				linkageSql = DDI.getLinkageSql();
	    				int count = DDI.getCount();
	    				sqlResultMap.put("exeSql_" + s,linkageSql+"========count:"+count);
	    			}
	        	}
    			Map<String,Object> assignInfo = new HashMap<String,Object>();
    			if(!changeValue.isEmpty())
    				assignInfo.put("changeValue",changeValue);
    			if(!addDetailInfo.isEmpty())
    				assignInfo.put("addDetailRow", addDetailInfo);
    			if(showAI)
					assignInfo.put("linkageSql", TextUtil.toBase64(linkageSql));
				assignInfo.put("resultOutOfLimit", resultOutOfLimit);
    			if (resultOutOfLimit){   //如果超出限制，sql传到前台
					assignInfo.put("showsql", linkageSql);
				}
    			result.put("assignInfo_"+datainputid, assignInfo);
				linkageSqlMap.put("linkagesql_"+datainputid,sqlResultMap);
        	}
        }
		this.syncSameTriValidResult();
		if (needWrite){
			//联动结果回写
			linkageLogBiz.setLinkageResult(result);
			linkageLogBiz.setLinkageSqlMap(linkageSqlMap);
			new Thread(linkageLogBiz).start();
		}
        return result;
    }

    private FieldValueBean buildValueObj(String fieldValue, FieldInfo info, String fieldMark){
		int requestid = Util.getIntValue(Util.null2String(request.getParameter("requestid")));
		Map<String,Object> otherParams = new HashMap<>();
		String cusDependFieldValues = Util.null2String(request.getParameter("customDepend_"+fieldMark));
		if(!"".equals(cusDependFieldValues))
			otherParams.put("cusDependFieldValues", cusDependFieldValues);
		if(info.getHtmltype()==6) {
			otherParams.putAll(ParamUtil.request2Map(request));
			otherParams.put("user", user);
			//联动赋值的，都应该是可以删除的
			otherParams.put("nodetype","0");
			BaseBean baseBean = new BaseBean();
			baseBean.infoLog(Module.WORKFLOW,"字段联动附件requestid=" + requestid + ",fieldid="+fieldMark+",原fieldvalue=" + fieldValue);
			fieldValue = EncryptConfigBiz.getDecryptData(fieldValue);
			String newdocids = "";
			try {
				for (String docid : fieldValue.split(",")) {
					if (docid.trim().isEmpty()) continue;
					//如果没有符合条件的附件作为正文，则复制一份公共的空白文档作为正文
					DocManager docManager = new DocManager();
					docManager.resetParameter();
					docManager.setId(Util.getIntValue(docid));
					docManager.getDocInfoById();
					int newdocid = docManager.copyDoc();
					newdocids += "," + newdocid;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			fieldValue = newdocids.length() == 0 ? "" : newdocids.substring(1);
			baseBean.infoLog(Module.WORKFLOW,"字段联动附件,新fieldvalue=" + fieldValue);
			int detailtype = info.getDetailtype();
			FieldValueBean valueBean = new FieldValueBean();
			valueBean.setSpecialobj(FileBiz.getFileFieldSpecialObj(fieldValue,detailtype,otherParams)) ;
			valueBean.setValue(fieldValue);
			return valueBean;
		}else{
		FieldValueBean valueBean = RequestFormBiz.generateFieldValueObj(fieldValue, info, user.getLanguage(), requestid,otherParams);
		return valueBean;
	}
	}

	private FieldValueBean buildClearObj(String sameTriKey, boolean hasValidResult){
		FieldValueBean clearobj = new FieldValueBean();
		clearobj.setValue("");
		if(!hasValidResult){
			if(emptyResultClearObj.containsKey(sameTriKey))
				clearobj = emptyResultClearObj.get(sameTriKey);
			else
				emptyResultClearObj.put(sameTriKey, clearobj);
		}
		return clearobj;
	}

	private void syncSameTriValidResult(){
    	for(Map.Entry<String,FieldValueBean> entry: this.vaildResultChangeObj.entrySet()){
			FieldValueBean source = entry.getValue();
			if(emptyResultClearObj.containsKey(entry.getKey())){
				FieldValueBean clearobj = emptyResultClearObj.get(entry.getKey());
				clearobj.setValue(source.getValue());
				clearobj.setSpecialobj(source.getSpecialobj());
			}
		}
	}
    
    @Override
	public BizLogContext getLogContext() {
		return null;
	}
	    
    public String getEntryType(String entryid){
    	RecordSet rs = new RecordSet();
    	String type = "";
    	String sql = " SELECT type FROM Workflow_DataInput_entry where id = "+entryid;
    	rs.executeSql(sql);
    	if(rs.next()){
    		type = rs.getString("type");
    	}
    	return type;
    }
    
}